package com.superb.allocation.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.superb.allocation.api.dto.Dict;
import com.superb.allocation.api.dto.DictTree;
import com.superb.allocation.api.entity.AllocationDictType;
import com.superb.allocation.service.AllocationDictTypeService;
import com.superb.common.core.annotation.SuperbDataScope;
import com.superb.common.core.annotation.SuperbRestMapping;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.superb.common.core.model.Result;
import com.superb.common.redis.key.KeyType;
import com.superb.common.redis.key.RedisKey;
import com.superb.common.redis.utils.RedisUtils;
import com.superb.common.utils.StringUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.superb.common.database.vo.BatchId;
import com.superb.common.database.vo.PageParams;
import com.superb.allocation.api.entity.AllocationDict;
import com.superb.allocation.service.AllocationDictService;

import jakarta.annotation.Resource;

import java.util.ArrayList;
import java.util.List;

/**
 * 数据字典;(allocation_dict)表控制层
 * @Author: ajie
 * @CreateTime: 2024-6-18
 */
@SuperbDataScope
@Tag(name = "数据字典接口")
@SuperbRestMapping("/dict")
@ApiSupport(author = "阿杰：ajie20999@163.com")
public class AllocationDictController {

    @Resource
    private AllocationDictService allocationDictService;
    @Resource
    private AllocationDictTypeService allocationDictTypeService;

    @PostMapping("type/pageQuery")
    @ApiOperationSupport(order = 1)
    @SaCheckPermission("allocation:dict:manage")
    @Operation(summary = "字典分类分页查询", description = "权限: allocation:dict:manage<br>")
    public Result<Page<AllocationDictType>> pageQuery(@RequestBody PageParams<AllocationDictType> pageParams) {
        AllocationDictType params = pageParams.getParams();
        LambdaQueryWrapper<AllocationDictType> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotBlank(params.getName()), AllocationDictType::getName, params.getName());
        lqw.like(StringUtils.isNotBlank(params.getCode()), AllocationDictType::getCode, params.getCode());
        if (StringUtils.isNotEmpty(params.getType())) {
            if (params.getType() == 1) {
                lqw.isNull(AllocationDictType::getParentId);
            }
            lqw.eq(StringUtils.isNotBlank(params.getType()), AllocationDictType::getType, params.getType());
        }
        lqw.orderByAsc(AllocationDictType::getSort);
        Page<AllocationDictType> result = allocationDictTypeService.page(pageParams.getPage(), lqw);
        if (params.getType() == 1) {
            result.setRecords(allocationDictTypeService.getChildren(result.getRecords()));
        }
        return Result.success(result);
    }

    @PostMapping("type/dictQuery")
    @ApiOperationSupport(order = 1)
    @Operation(summary = "根据字典分类类型获取字典分类列表", description = "权限: allocation:dict:manage<br>", parameters = {
            @Parameter(name = "dictType", description = "字典类型CODE", required = true, in = ParameterIn.PATH)
    })
    @SaCheckPermission("allocation:dict:manage")
    public Result<Page<AllocationDict>> dictQuery(@RequestBody PageParams<AllocationDict> pageParams) {
        AllocationDict params = pageParams.getParams();
        LambdaQueryWrapper<AllocationDict> lqw = new LambdaQueryWrapper<>();
        lqw.eq(AllocationDict::getDictType, params.getDictType())
                .like(StringUtils.isNotBlank(params.getName()), AllocationDict::getName, params.getName())
                .eq(StringUtils.isNotBlank(params.getStatus()), AllocationDict::getStatus, params.getStatus())
                .orderByAsc(AllocationDict::getSort);
        return Result.success(allocationDictService.page(pageParams.getPage(), lqw));
    }

    @PostMapping("type/insert")
    @ApiOperationSupport(order = 2)
    @SaCheckPermission("allocation:dict:manage")
    @Operation(summary = "新增字典分类信息", description = "权限: allocation:dict:manage<br>")
    public Result<Boolean> insertType(@RequestBody @Validated AllocationDictType allocationDict) {
        long count = allocationDictTypeService.count(Wrappers.<AllocationDictType>lambdaQuery()
                .eq(AllocationDictType::getCode, allocationDict.getCode()));
        if (count > 0) {
            return Result.error("该字典类型已存在相同配置值");
        }
        if (allocationDictTypeService.save(allocationDict)) {
            return Result.success();
        }
        return Result.error();
    }

    @PostMapping("type/update")
    @ApiOperationSupport(order = 3)
    @SaCheckPermission("allocation:dict:manage")
    @Operation(summary = "修改字典分类信息", description = "权限: allocation:dict:manage<br>")
    public Result<Boolean> updateType(@RequestBody @Validated AllocationDictType allocationDict) {
        if (allocationDictTypeService.updateById(allocationDict)) {
            RedisKey redisKey = new RedisKey(KeyType.PER, "allocation:TREEDICT");
            RedisUtils.build().hash().del(redisKey, allocationDict.getCode());
            RedisKey redisKey2 = new RedisKey(KeyType.PER, "allocation:DICT");
            RedisUtils.build().hash().del(redisKey2, allocationDict.getCode());
            return Result.success();
        }
        return Result.error();
    }

    @PostMapping("insert")
    @ApiOperationSupport(order = 2)
    @SaCheckPermission("allocation:dict:manage")
    @Operation(summary = "新增字典", description = "权限: allocation:dict:manage<br>")
    public Result<Boolean> insert(@RequestBody @Validated AllocationDict allocationDict) {
        long count = allocationDictService.count(Wrappers.<AllocationDict>lambdaQuery().eq(AllocationDict::getDictType, allocationDict.getDictType()).eq(AllocationDict::getCode, allocationDict.getCode()));
        if (count > 0) {
            return Result.error("该字典类型已存在相同配置值");
        }
        if (allocationDictService.save(allocationDict)) {
            return Result.success();
        }
        return Result.error();
    }

    @PostMapping("update")
    @ApiOperationSupport(order = 3)
    @SaCheckPermission("allocation:dict:manage")
    @Operation(summary = "修改字典", description = "权限: allocation:dict:manage<br>")
    public Result<Boolean> update(@RequestBody @Validated AllocationDict allocationDict) {
        if (allocationDictService.updateById(allocationDict)) {
            RedisKey redisKey = new RedisKey(KeyType.PER, "allocation:DICT");
            RedisUtils.build().hash().del(redisKey, allocationDict.getDictType());
            return Result.success();
        }
        return Result.error();
    }


    @GetMapping("translate/{dictType}")
    @ApiOperationSupport(order = 3)
    @Operation(summary = "普通字典翻译")
    public Result<List<Dict>> translate(@PathVariable String dictType) {
        RedisKey redisKey = new RedisKey(KeyType.PER, "allocation:DICT");
        List<Dict> list = RedisUtils.build().hash().getNullSet(redisKey, dictType, () -> {
            List<AllocationDict> dicts = allocationDictService.list(Wrappers.<AllocationDict>lambdaQuery().eq(AllocationDict::getDictType, dictType).orderByAsc(AllocationDict::getSort));
            List<Dict> data = new ArrayList<>();
            for (AllocationDict dict : dicts) {
                Dict value = new Dict();
                value.setLabel(dict.getName());
                value.setValue(dict.getCode());
                value.setType(dict.getType());
                value.setDisabled(dict.getStatus() == 1);
                data.add(value);
            }
            return data;
        }, util -> util.hash().getArray(redisKey, dictType, Dict.class));
        return Result.success(list);
    }

    @GetMapping("translate/tree/{dictType}")
    @ApiOperationSupport(order = 3)
    @Operation(summary = "树型字典翻译")
    public Result<List<DictTree>> treeTranslate(@PathVariable String dictType) {
        RedisKey redisKey = new RedisKey(KeyType.PER, "allocation:TREEDICT");
        List<DictTree> list = RedisUtils.build().hash().getNullSet(redisKey, dictType, () -> {
            // 获得本级字典
            AllocationDictType info = allocationDictTypeService.getOne(Wrappers.<AllocationDictType>lambdaQuery().eq(AllocationDictType::getCode, dictType));
            // 得到子级字典
            return allocationDictTypeService.levelDict(info.getId());
        }, util -> util.hash().getArray(redisKey, dictType, DictTree.class));
        return Result.success(list);
    }
}